package com.lanchetech.admin.service.impl;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.CollectionUtils;
import com.baidu.fsg.uid.UidGenerator;
import com.lanchetech.admin.service.AfterSaleService;
import com.lanchetech.admin.service.VipService;
import com.lanchetech.bean.request.AfterSalePageReq;
import com.lanchetech.bean.response.*;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.OrderSkuVO;
import com.lanchetech.common.enums.*;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.service.*;
import com.raycloud.open.sdk.api.request.KdzsPrintTradeRefundRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AfterSaleServiceImpl implements AfterSaleService {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    AfterSaleMapper afterSaleMapper;

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    OrderSkuMapper orderSkuMapper;

    @Autowired
    SkuMapper skuMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    WxPayService wxPayService;

    @Resource
    UidGenerator uidGenerator;

    @Autowired
    OrderAddressMapper orderAddressMapper;

    @Autowired
    UserCommissionMapper userCommissionMapper;

    @Value("${domain.url}")
    private String domainUrl;

    @Autowired
    ColumnCourseAuthMapper columnCourseAuthMapper;

    @Autowired
    ConsumptionService consumptionService;


    @Autowired
    HipoConfigMapper hipoConfigMapper;

    @Autowired
    IdentityMapper identityMapper;

    @Autowired
    VipService vipService;

    @Autowired
    CardFlowMapper cardFlowMapper;

    @Autowired
    UserMapper userMapper;


    @Autowired
    RewardQueueMapper rewardQueueMapper;

    @Autowired
    BonusCountMapper bonusCountMapper;

    @Autowired
    OrderPayMapper orderPayMapper;

    @Autowired
    TenantFlowMapper tenantFlowMapper;

    @Autowired
    TenantMapper tenantMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    ShopMapper shopMapper;

    @Value("${wx.pay.appId}")
    private String miniAppId;

    @Value("${wx.app.appId}")
    private String appAppId;

    @Autowired
    FinanceService financeService;

    @Autowired
    KuaidizsService kuaidizsService;

    @Autowired
    InviteFirstBuyMapper inviteFirstBuyMapper;

    @Autowired
    CommonAfterSaleService commonAfterSaleService;

    @Override
    public ResultData<BasePageResp<AfterSaleResp>> getAfterSalePage(AfterSalePageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<AfterSaleResp> list = afterSaleMapper.findAllBackPage(req);
        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }

        List<Long> skuIds = new ArrayList<>();
        list.forEach(item -> {
            if (!skuIds.contains(item.getSkuId())) {
                skuIds.add(item.getSkuId());
            }
        });

        // 获取商品sku信息
        List<Sku> skuList = skuMapper.findAllByIds(skuIds);
        Map<Long, Sku> skuMap = new HashMap<>();
        Map<Long,Shop> shopMap = daoService.getShopMap(list.stream().map(AfterSaleResp::getTenantId).collect(Collectors.toList()));
        skuList.stream().forEach(item -> skuMap.put(item.getId(), item));

        list.stream().forEach((item) -> {
            item.setImage(skuMap.get(item.getSkuId()).getImage());
            item.setSpecNames(skuMap.get(item.getSkuId()).getSpecNames());
            item.setSpecValues(skuMap.get(item.getSkuId()).getSpecValues());
            item.setTenantAvatar(shopMap.get(item.getTenantId()).getAvatar());
            item.setTenantName(shopMap.get(item.getTenantId()).getShopName());
        });

        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public void exportAfterSaleExcel(AfterSalePageReq req, HttpServletResponse response) throws IOException {
        ResultData<BasePageResp<AfterSaleResp>> resp = getAfterSalePage(req);
        List<AfterSaleResp> afterSaleRespList = resp.getValue().getData();
        if (!CollectionUtils.isEmpty(req.getCheckedIds())) {
            afterSaleRespList.stream().filter(item -> req.getCheckedIds().contains(item.getId()));
        }
        String fileName = new String(("商品售后列表导出数据.xlsx").getBytes(), "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        EasyExcel.write(response.getOutputStream(), AfterSaleResp.class).sheet("商品售后列表导出数据").doWrite(resp.getValue().getData());
    }

    @Override
    public ResultData<AfterSaleDetailResp> getAfterSaleDetail(Long id) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(id);
        Orders orders = ordersMapper.findOneByTradeNo(afterSale.getTradeNo());
        Shop shop = shopMapper.selectByPrimaryKey(afterSale.getTenantId());
        User user = userMapper.selectByPrimaryKey(afterSale.getUserId());
        AfterSaleDetailResp resp = AfterSaleDetailResp.builder()
                .afterSale(afterSale)
                .orders(orders)
                .orderSku(orderSkuMapper.selectByPrimaryKey(afterSale.getOrderSkuId()))
                .sku(skuMapper.selectByPrimaryKey(afterSale.getSkuId()))
                .spu(spuMapper.selectByPrimaryKey(afterSale.getSpuId()))
                .orderAddress(orderAddressMapper.findOneByOrderId(orders.getId()))
                .tenantName(shop.getShopName())
                .tenantAvatar(shop.getAvatar())
                .userNickname(user.getNickname())
                .userAvatar(user.getAvatar())
                .build();

        return new ResultData(resp);
    }

    @Override
    public BaseResp editAfterSaleLogistics(AfterSale req) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());

        if (AfterSaleTypeEnum.EXCHANGE.getType().equals(afterSale.getType())
                && (AfterSaleStatusEnum.CONFIRM.getStatus().equals(afterSale.getStatus()) || AfterSaleStatusEnum.REFUNDED.getStatus().equals(afterSale.getStatus()))
        ) {
            afterSale.setDeliveryLogisticsCompany(req.getDeliveryLogisticsCompany());
            afterSale.setDeliveryLogisticsNumber(req.getDeliveryLogisticsNumber());
            afterSale.setStatus(AfterSaleStatusEnum.REFUNDED.getStatus());
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }

    @Override
    public BaseResp rejectAfterSale(AfterSale req) {

        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());

        if (!AfterSaleStatusEnum.REFUNDED.getStatus().equals(afterSale.getStatus())) {
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setStatus(AfterSaleStatusEnum.REJECT.getStatus());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }

    @Override
    public BaseResp confirmAfterSale(AfterSale req) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());
        if (AfterSaleStatusEnum.PROCESSING.getStatus().equals(afterSale.getStatus())) {
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setStatus(AfterSaleStatusEnum.CONFIRM.getStatus());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }

    @Override
    public String refundNotify(String xmlData) {
        wxPayService.getConfig().setAppId(xmlData.indexOf(miniAppId) > -1 ? miniAppId : appAppId);
        wxPayService.getConfig().setTradeType(xmlData.indexOf(miniAppId) > -1 ? "JSAPI" : "APP");

        WxPayRefundNotifyResult wxPayRefundNotifyResult;
        try {
            wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);
            // 检查微信退款成功的回调是否是他人伪造
            wxPayRefundNotifyResult.checkResult(wxPayService, "MD5", true);
        } catch (WxPayException e) {
            log.error("退款失败，失败信息:{}", e);
            return WxPayNotifyResponse.fail("退款失败");
        }

        //判断返回状态信息是否正确，是否真的退款了
        if ("SUCCESS".equals(wxPayRefundNotifyResult.getReturnCode())) {
            WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();
            //判断退款状态
            if ("SUCCESS".equals(reqInfo.getRefundStatus())) {
                String refundNo = reqInfo.getOutRefundNo();
                commonAfterSaleService.refundNotifyComplete(refundNo);

                return WxPayNotifyResponse.success("退款成功！");
            }
        }
        return WxPayNotifyResponse.fail("回调有误!");
    }
}